home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
MCASM.RAR
/
MC_ASM.EXE
/
WROX_ASM
/
CH13
/
MEMVIEW.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-11-15
|
10KB
|
545 lines
; This program prints out the list of MCBs
; (Memory Control Blocks) from the PC memory.
; When run with the switch /D, it prints out
; the list of drivers.
; Demo program for ExpAsm Chapter 13 Memory Management under 1Mb
; written by Yuri Kisselev. Autumn 1991 - Summer 1994 ^Z Minsk RB.
.286
dosseg
.model small
.stack 100h
.data
addr_str db 'Address'
sys_str db 'System'
name_str db 'Name'
type_str db 'Type'
size_str db 'Size'
dat db 'Data'
cod db 'Code'
env db 'Environment'
prg db 'Program'
msd db 'MSDOS'
fre db 'Free'
unkn db 'Unknown'
OldDOS db 'Incorrect DOS version .',13,10,'$'
hex db '0123456789ABCDEF' ; Table for hex convertion
buff_str db 50 dup (0),13,10,'$'; String buffer
flag_link_UMB db 0
.code
Start:
mov ax,@data
mov ds,ax ; Load data segment
mov bx,ss
sub bx,ax
shl bx,4
cli
mov ss,ax ; Load stack pointer
add sp,bx
sti
mov bx,sp ; Calculate the size of program
; memory block
add bx,15 ; Round up to next paragraph
shr bx,4
add ax,bx
mov bx,es
sub ax,bx
mov bx,ax
mov ah,4ah
int 21h ; Resize program memory block
mov ah,30h
int 21h ; Get DOS version
cmp al,5 ; Check DOS version (5.0)
jnb ok_dos
mov ah,9
lea dx,OldDOS
int 21h
mov ah,4ch
int 21h ; terminate program
ok_dos:
mov ax,5802h
int 21h ; Get Upper Memory link
mov flag_link_UMB,al ; Save it
mov ax,5803h
mov bx,1
int 21h ; Set upper memory link
; Look for /d in command line (show device drivers)
mov di,81h
mov cl,es:[di-1]
mov al,'/'
repne scasb
jne show_mcb
cmp byte ptr es:[di],'D'
je show_drivers
cmp byte ptr es:[di],'d'
je show_drivers
show_mcb:
; show the MCBs
call Display_MCB
jmp short exit_prg
show_drivers:
; show the DRVs
call Display_DRV
exit_prg:
mov ax,5803h
xor bx,bx
mov bl,flag_link_UMB
int 21h ; Restore upper memory link
mov ax,4c00h
int 21h ; Exit program
; show drivers chain
Display_DRV proc near
xor cx,cx ; Fill header string
mov ax,ds
mov es,ax
mov di,offset buff_str
mov dx,di
inc di
mov si,offset addr_str
mov cl,7
rep movsb
add di,7
mov si,offset name_str
mov cl,4
rep movsb
mov ah,9
int 21h ; Print header
mov di,offset buff_str
mov ax,2d2dh
mov cl,15
rep stosw ; "-----------"
mov ah,9
int 21h
mov ah,52h
int 21h ; Get DOS List Of Lists (ES:BX)
add bx,22h ; ES:BX -> NUL device
next_drv:
mov dx,es
mov ax,ds
mov es,ax
mov di,offset buff_str
mov si,di
mov cx,25
mov ax,2020h
rep stosw ; Fill string with spaces
mov es,dx
push bx
push bx
xor bx,bx
mov ax,es
call PutHexWord ; Put driver segment
mov byte ptr [si],':'
inc si
pop ax
call PutHexWord ; Put driver offset
pop bx
add si,5
test byte ptr es:[bx+5],80h
jz block_dev ; Jump if block device
mov cl,4 ; copy device name (blank-padded)
mov di,10
next_w:
mov ax,es:[bx+di]
mov [si],ax
add si,2
add di,2
loop next_w
inc si
mov ax,es
cmp ax,0070h
jbe addr_nextdrv
push es
push si
dec ax
mov es,ax
mov cl,8 ; copy driver's name
mov di,cx
next_chard:
mov al,es:[bx+di]
cmp al,0
jz str_end1
; check chars : " * + , . \ ; : > < = ? [ ]
cmp al,32
jb unknown_drvname
cmp al,34
je unknown_drvname
cmp al,45
je ok_char1
cmp al,42
jb ok_char1
cmp al,47
jbe unknown_drvname
cmp al,58
jb ok_char1
cmp al,63
jbe unknown_drvname
cmp al,91
jb ok_char1
cmp al,93
jbe unknown_drvname
cmp al,127
ja unknown_drvname
ok_char1:
mov [si],al
inc di
inc si
loop next_chard
str_end1:
pop ax
pop es
jmp short addr_nextdrv
unknown_drvname:
pop si
pop es
jmp short addr_nextdrv
block_dev: ; Block devices show as A: - C:
mov word ptr [si],':'*256+'A'
mov word ptr [si+2],'-'*256+' '
mov word ptr [si+4],'C'*256+' '
mov byte ptr [si+6],':'
add si,7
addr_nextdrv: ; output string
mov cx,si
sub cx,offset buff_str
mov si,offset buff_str
mov ah,2
next_ch:
mov dl,[si]
int 21h
inc si
loop next_ch
mov dl,13
int 21h
mov dl,10
int 21h
les bx,es:[bx]
cmp bx,-1 ; FFFF = last device in the chain
je exit_dispdrv
jmp next_drv
exit_dispdrv:
ret
Display_DRV endp
Display_MCB proc near
call put_head_table
mov ah,52h
int 21h ; Get DOS List Of Lists (ES:BX)
mov es,es:[bx-2] ; Get Root Memory Control Block
next_block:
mov dx,es
mov bx,ds
mov es,bx
mov di,offset buff_str
mov cx,25
mov ax,2020h
rep stosw
mov es,dx ; Fill string buffer with spaces
call PutAddrSizeBlock ; print address & size of block
call PutNameTypeBlock ; print name & type of block
mov dx,offset buff_str
mov ah,9
int 21h ; Output string
cmp byte ptr es:[0],'Z' ; Last block ?
je exit_dispmcb ; yes
; no
mov ax,es
add ax,es:[3]
inc ax
mov es,ax ; ES -> points to the next MCB
jmp next_block
exit_dispmcb:
ret
Display_MCB endp
; Procedure to print the header string for memory block
put_head_table proc near
xor cx,cx
mov ax,ds
mov es,ax
mov di,offset buff_str
mov dx,di
inc di
mov si,offset addr_str
mov cl,7
rep movsb
add di,7
mov si,offset name_str
mov cl,4
rep movsb
add di,9
mov si,offset type_str
mov cl,4
rep movsb
add di,9
mov si,offset size_str
mov cl,4
rep movsb
mov ah,9
int 21h
mov di,offset buff_str
mov ax,2d2dh
mov cl,25
rep stosw ; "--------------"
mov ah,9
int 21h
ret
put_head_table endp
; Put address and size of memory block
PutAddrSizeBlock proc near
mov ax,es
mov dx,ax
shr ax,12
shl dx,4
mov bx,offset buff_str
mov si,1
call PutHexByte ; Put high part of address
mov ax,dx
call PutHexWord ; Put low part
mov si,45
mov ax,es:[3] ; AX = block size (in paragraphs)
inc ax ; +1
mov dx,ax
shr dx,12
shl ax,4 ; DX:AX = block size
call PutDecDWord ; Put block size
ret
PutAddrSizeBlock endp
; Put name and type of memory block
PutNameTypeBlock proc near
xor cx,cx
mov ax,es:[1] ; AX = owner field
or ax,ax ; 0 - free block
jnz no_free_block
jmp dos_block
no_free_block:
cmp ax,8 ; 8 - block owned by DOS
jne no_dos_block
jmp dos_block
no_dos_block:
push es
mov dx,es
mov es,ax
inc dx
cmp dx,es:[2ch] ; Environment block ?
jne no_env_block ; NO
; YES
mov di,offset buff_str+25 ; Put "Environment"
mov si,offset env
mov cl,11
jmp short host_name
no_env_block:
mov ax,es
cmp ax,dx ; Program block ?
jne no_progr ; NO
; YES
mov di,offset buff_str+27 ; Put "Program"
mov si,offset prg
mov cl,7
jmp short host_name
no_progr:
; if block is neither env or prg,
; it is data block (may be)
mov di,offset buff_str+28 ; Put "Data"
mov si,offset dat
mov cl,4
host_name:
call str_cpy ; Put host's name
mov ax,es
dec ax
mov es,ax
; check filename symbols
; check chars : " * + , . \ ; : > < = ? [ ]
mov cl,8
mov di,cx
chk_char:
mov al,es:[di]
or al,al
jz end_chk
cmp al,32
jbe unknown_name
cmp al,34
je unknown_name
cmp al,45
je ok_char
cmp al,42
jb ok_char
cmp al,47
jbe unknown_name
cmp al,58
jb ok_char
cmp al,63
jbe unknown_name
cmp al,91
jb ok_char
cmp al,93
jbe unknown_name
ok_char:
inc di
loop chk_char
end_chk:
cmp di,8
je unknown_name
mov cl,8 ; Copy owner's name from
mov di,cx ; MCB (ASCIIZ or 8 chars)
mov si,offset buff_str+14
next_char:
mov al,es:[di]
cmp al,0
jz str_end
mov [si],al
inc di
inc si
loop next_char
str_end:
pop es
ret
unknown_name: ; There's a spy in your system (joke)
pop es
mov di,offset buff_str+14 ; Put "Unknown"
mov si,offset unkn
mov cl,6
jmp short str_cpy
dos_block:
; Copy string "MSDOS"
mov di,offset buff_str+14
mov si,offset msd
mov cl,5
nextb:
mov dl,[si]
mov [di],dl
inc si
inc di
loop nextb
or ax,ax
jz free_block ; Jump if free block
add di,6
cmp word ptr es:[8],'C'*256+'S' ; System Code ?
jne no_syscode ; NO
; YES
mov si,offset sys_str ; Put "System"
mov cl,6
call str_cpy
inc di
mov si,offset cod ; Put "Code"
mov cl,4
jmp short str_cpy
no_syscode:
; If not SC then SD "System Data"
mov si,offset sys_str ; Put "System"
mov cl,6
call str_cpy
inc di
mov si,offset dat ; Put "Data"
mov cl,4
jmp short str_cpy
free_block:
; ooo! free block "free"
mov si,offset fre ; Put "free"
add di,9
mov cl,4
; str_cpy copeis blocks from DS:SI to DS:DI
; CX - bytes count
str_cpy:
lodsb
mov [di],al
inc di
loop str_cpy
ret
PutNameTypeBlock endp
; convert byte to hex
; AL = 8 bit value to convert
; ds:[bx+si] <- string
PutHexByte proc near
push bx
add si,bx
lea bx,hex
mov ah,al
shr al,4
xlat ; Convert high half byte
mov [si],al
mov al,ah
and al,0fh
xlat ; Convert low half byte
mov [si+1],al
add si,2
pop bx
sub si,bx
ret
PutHexByte endp
; Covert word to hex
; AX = 16 bit value to convert
PutHexWord proc near
push ax
mov al,ah
call PutHexByte
pop ax
call PutHexByte
ret
PutHexWord endp
; Binary to ASCII conversion (right aligned)
; DX:AX = 32 bit value to convert
PutDecDword proc near
push bx
add si,bx
mov bx,10
next_digitd:
div bx ; Convert to decimal digits
add dl,'0'
mov [si],dl
dec si
xor dx,dx
or ax,ax
jnz next_digitd
pop bx
sub si,bx
ret
PutDecDword endp
end Start